package com.prb.consumer.handler;

import com.alibaba.fastjson.JSONObject;
import com.prb.common.protocol.RpcResponse;
import com.prb.common.protocol.SmartCarProtocol;
import com.prb.common.statistical.TimeMetrics;
import com.prb.consumer.proxy.RpcConsumer;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelPromise;
import io.netty.handler.timeout.IdleStateEvent;

import java.util.concurrent.locks.LockSupport;

public class ClientHandler extends ChannelInboundHandlerAdapter {

    private ChannelPromise channelPromise;
    private ChannelHandlerContext ctx;


    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {

        super.channelActive(ctx);
        this.ctx = ctx;
    }

    /**
     * 收到服务端数据
     */
    @Override
    public void channelRead(ChannelHandlerContext channelHandlerContext, Object rpcResponse) throws Exception {

    // 用于获取客户端发来的数据信息
        SmartCarProtocol body = (SmartCarProtocol) rpcResponse;
        RpcResponse result = JSONObject.parseObject(new String(body.getContent()) , RpcResponse.class);

        //计算调用时间
        TimeMetrics.instance.calculateTime(result.getServerName());

        RpcResponse response = RpcConsumer.responseMap.get(result.getInvokeId());
        //解锁线程
        //LockSupport.unpark(response.getThread());
        //设置返回值
        response.setResult(result.getResult());
        channelPromise.setSuccess();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        super.exceptionCaught(ctx, cause);
        ctx.close();
    }

    /**
     * 定时处理
     *
     * @param ctx
     * @param evt
     * @throws Exception
     */
    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) {
        try{
            if (evt instanceof IdleStateEvent) {
                ctx.writeAndFlush("ERROR");
            } else {
                ctx.close();
                System.out.println("request handler error");
                super.userEventTriggered(ctx, evt);
            }
        }catch(Exception e){
            System.out.println(e.getMessage());
        }
    }

    public ChannelPromise send(Object message) {

        channelPromise = ctx.newPromise();
        ctx.writeAndFlush(message);

        return channelPromise;
    }

}
